package ws;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import model.BusInfo;
import model.Route;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.utils.DB;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;

public class KmlOperation {
	private final String TAGBUS = "Placemark";
	private final String URLKML = "../model/doc.kml";
	
	public Document loadXMLFromString(String xml) throws Exception
	{
	    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	    DocumentBuilder builder = factory.newDocumentBuilder();
		InputStream is = getClass().getResourceAsStream(URLKML);
	    return builder.parse(is);
	}
	
	public static void main(String a[]) {
		KmlOperation ko = new KmlOperation();
		BusInfo bi = ko.getBusForCode(11);
		bi.toString();
		//ko.saveAllLineBD(); //Salva todos os dados do kml no banco de dados
		ko.linesByPoint(-3.737012, -38.571775, -3.736905, -38.530533); //linhas que passam proximo as coordenadas;
		ko.linesByPoint(-3.77596, -38.563042, -3.737333, -38.528881);
		//ko.getAllLines();
	}
	
	public BusInfo getBusForCode(int cod){
		BusInfo bi = null;
		try {
			Document doc = loadXMLFromString(URLKML);
			NodeList nl = doc.getElementsByTagName(TAGBUS);
			for(int i=0;i<nl.getLength();i++){
				NodeList content = nl.item(i).getChildNodes();
				String[] name = content.item(1).getTextContent().split(" - ");
				if(cod == Integer.parseInt(name[0])){
					bi = new BusInfo();
					bi.setCod(Integer.parseInt(name[0]));
					bi.setName(name[1].replace("/1", ""));
					bi.setDescription(content.item(3).getTextContent());
				}		
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bi;
	}
	/**
	 * Salva o conteúdo do documento kml no banco de dados
	 */
	public void saveAllLineBD(){
		BusInfo bi = null;
		try {
			Document doc = loadXMLFromString(URLKML);
			NodeList nl = doc.getElementsByTagName(TAGBUS);
			for(int i=0;i<nl.getLength();i++){
				NodeList content = nl.item(i).getChildNodes();
				String[] name = content.item(1).getTextContent().split(" - ");
					bi = new BusInfo();
					bi.setCod(Integer.parseInt(name[0]));
					bi.setName(name[1].replace("/1", ""));
					bi.setDescription(content.item(3).getTextContent());
					bi.setRoute(transformRoute(content.item(7).getChildNodes().item(3).getTextContent().trim()));
					DB.getSession();
					try{
						DB.save(bi);
					}catch(Exception e){
						System.out.println("Erro ao inserir no banco de dados! \n\n"+e);
					}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public List<String> getAllLines(){
		List<String> lines = new ArrayList<String>();
		try {
			Document doc = loadXMLFromString(URLKML);
			NodeList nl = doc.getElementsByTagName(TAGBUS);
			for(int i=0;i<nl.getLength();i++){
				NodeList content = nl.item(i).getChildNodes();
				lines.add(content.item(1).getTextContent());
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return new ArrayList(new HashSet(lines));
	}
	
	/**
	 * @param route
	 * @return lista de objetos route gerados através da string passada por parâmetro
	 */
	public Collection<Route> transformRoute(String route){
		Collection<Route> routes = new ArrayList<Route>();
		Route r = null;
		String[] tRoute = route.split(",0");
		for(int i=0;i<tRoute.length;i++){
			r = new Route();
			String point[] = tRoute[i].split(",");
			r.setLocation(new Point(new Coordinate(Double.parseDouble(point[0].trim()), Double.parseDouble(point[1].trim())), new PrecisionModel(), 4326));
			System.out.println("Pontos: "+r.getLocation().getX()+","+r.getLocation().getY());
			routes.add(r);
		}
		return routes;
	}
	
	/**
	 * @param latiO
	 * @param longO
	 * @param latiF
	 * @param longF
	 * @return Retorna uma lista de objetos businfo que passam proximos aos pontos enviados por parâmetro
	 */
	public List<BusInfo> linesByPoint(double latiO, double longO, double latiF, double longF){
		List<BusInfo> result = BusInfo.getLinesNextCoordenate(latiO, longO, latiF, longF);
//		for(BusInfo b: result)
//			System.out.println("Linhas: "+b.getCod()+" "+b.getName());
		return result;
	}
}
